/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dyniablaster.logic;

import dyniablaster.graphics.*;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.*;
import java.util.Vector;

/**
 *
 * @author Damian2
 */
public class DyniaManager extends LayerManager
{
    int CANVAS_X;
    int CANVAS_Y;
    int DISP_WIDTH;
    int DISP_HEIGHT;
    int MIN_BUFFER = 60;
    int viewPortX = 0;
    int viewPortY = 0;
    int lastDirection = -1;
    int bombsTimes[] = {-1, -1, -1, -1, -1};

    private Timer timer;

    public 

    static int SPEED = 4;

    static int SQUARE_WIDTH = 16;

    DyniaBlasterCanvas myCanvas;
    DyniaBlasterDesign dyniaDesign;

    Sprite playerSprite;
    Sprite bomb;
    TiledLayer labirynt;
    TiledLayer floor;
    TiledLayer level;

    DyniaManager.SpriteAnimationTask playerSpriteAnimator;


    public DyniaManager(int x, int y, int width, int height, DyniaBlasterCanvas canvas)
    {
        myCanvas = canvas;
        CANVAS_X = x;
        CANVAS_Y = y;
        DISP_WIDTH = width;
        DISP_HEIGHT = height;
        timer = new Timer();
    }

    public void init() throws Exception
    {
        dyniaDesign = new DyniaBlasterDesign();
        playerSprite = dyniaDesign.getPlayer1();
        labirynt = dyniaDesign.getLabirynt();
        floor = dyniaDesign.getFloor();
        level = dyniaDesign.getLevel1();
        dyniaDesign.updateLayerManagerForScena(this);

        playerSpriteAnimator = new SpriteAnimationTask(playerSprite, false);
        timer.scheduleAtFixedRate(playerSpriteAnimator, 0, dyniaDesign.downDelay);

        System.gc();

    }

    public void paint(Graphics g) throws Exception
    {
        g.setColor(myCanvas.WHITE);
        // paint the background white to cover old game objects
        // that have changed position since last paint.
        // here coordinates are given
        // with respect to the graphics (canvas) origin:
        g.fillRect(0, 0, DISP_WIDTH, DISP_HEIGHT);

        // here coordinates are given
        // with respect to the LayerManager origin:
        setViewWindow(viewPortX, viewPortY, DISP_WIDTH, DISP_HEIGHT);
        // call the paint funstion of the superclass LayerManager
        // to paint all of the Layers
        
       
        paint(g, CANVAS_X, CANVAS_Y);
        //g.setColor(myCanvas.BLACK);
       // g.fillRect(0, 0, myCanvas.getWidth(), 15);
        //g.drawRect(viewPortX, viewPortY, viewPortX +20, viewPortY + 20);
       // g.setColor(myCanvas.WHITE);
       // g.drawString(String.valueOf(dyniaDesign.getDynia2(0).getX()+" "+dyniaDesign.getDynia2(0).getY()), 10, 0, Graphics.TOP | Graphics.LEFT);
    }

    public void update(int dt)
    {
        for(int i=0; i<5; i++)
        {
            if(bombsTimes[i] > 0)
            {
                bombsTimes[i] = bombsTimes[i] - dt;
                if(bombsTimes[i] <= 1000)
                    dyniaDesign.boom(i);

                if(bombsTimes[i] <= 0)
                {
                    dyniaDesign.destroyBomb(i);
                    bombsTimes[i] = -1;
                }
            }
        }

    }

    public int findPlace(int a)
    {
        int i=0;
        do
        {
            a = a - 16;
            i++;
        }
        while(a>0);

        if(a < -8)
            i--;

        return (i*16);
    }

    public void bomb() throws IOException
    {
        int sx = findPlace(this.playerSprite.getX());   //finidPlace zwraca pozycje tak zeby bomba lezala posrodku kratki
        int sy = findPlace(this.playerSprite.getY());

        int i = dyniaDesign.setBomb(sx, sy);
        if(i >= 0)
        {
            bombsTimes[i] = 3000;
        }

    }

    private void adjustViewport(int x, int y)
    {

        int sx = this.playerSprite.getX();
        int sy = this.playerSprite.getY();

        int xmin = this.viewPortX + MIN_BUFFER;
        int xmax = this.viewPortX + myCanvas.getWidth() - this.playerSprite.getWidth() - MIN_BUFFER;
        int ymin = this.viewPortY + MIN_BUFFER;
        int ymax = this.viewPortY + myCanvas.getHeight() - this.playerSprite.getHeight() - MIN_BUFFER;

        //if the sprite is not near the any screen edges don't adjust
        if (sx >= xmin && sx <= xmax && sy >= ymin && sy <= ymax)
        {
            return;
        }

        //if the sprite is moving left but isn't near the left edge of the screen don't adjust
        if (this.lastDirection == myCanvas.LEFT && sx >= xmin) {
            return;
        }
        //if the sprite is moving right but isn't near the right edge of the screen don't adjust
        if (this.lastDirection == myCanvas.RIGHT && sx <= xmax) {
            return;
        }
        //if the sprite is moving up but isn't at near top edge of the screen don't adjust
        if (this.lastDirection == myCanvas.UP && sy >= ymin) {
            return;
        }
        //if the sprite is moving down but isn't at near bottom edge of the screen don't adjust
        if (this.lastDirection == myCanvas.DOWN && sy <= ymax) {
            return;
        }

        //only adjust x to values that ensure the base tiled layer remains visible
        //and no white space is shown
        if (x < this.floor.getX())
        {
            this.viewPortX = this.floor.getX();
        }
        else if (x > this.floor.getX() - 16 + this.floor.getWidth() - myCanvas.getWidth())
        {
            this.viewPortX = this.floor.getX() - 16 + this.floor.getWidth() - myCanvas.getWidth();
        }
        else
        {
            this.viewPortX = x;
        }

        //only adjust y to values that ensure the base tiled layer remains visible
        //and no white space is shown
        if (y < this.floor.getY())
        {
            this.viewPortY = this.floor.getY();
        } 
        else if (y > this.floor.getY() - 16 + this.floor.getHeight() - myCanvas.getHeight())
        {
            this.viewPortY = this.floor.getY() - 16 + this.floor.getHeight() - myCanvas.getHeight();
        }
        else
        {
            this.viewPortY = y;
        }

        //adjust the viewport
        this.setViewWindow(this.viewPortX, this.viewPortY, myCanvas.getWidth(), myCanvas.getHeight());
    }

    public void requestMove(int hdirection, int vdirection) 
    {


        if(vdirection < 0)
        {
            playerSprite.move(0, -SPEED);
            if((playerSprite.collidesWith(labirynt, true))||(playerSprite.collidesWith(level, true)))
                playerSprite.move(0, SPEED);
            else 
            {
                this.adjustViewport(this.viewPortX, this.viewPortY - SPEED);
                if (lastDirection != myCanvas.UP)
                {
                    this.lastDirection = myCanvas.UP;
                    this.playerSprite.setFrameSequence(dyniaDesign.goUp);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if(vdirection > 0)
        {
            playerSprite.move(0, SPEED);
            //lastDirection = myCanvas.DOWN;
            if((playerSprite.collidesWith(labirynt, true))||(playerSprite.collidesWith(level, true)))
                playerSprite.move(0, -SPEED);
            else 
            {
                this.adjustViewport(this.viewPortX, this.viewPortY + SPEED);
                if (lastDirection != myCanvas.DOWN)
                {
                    this.lastDirection = myCanvas.DOWN;
                    this.playerSprite.setFrameSequence(dyniaDesign.goDown);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if (hdirection < 0)
        {
            playerSprite.move(-SPEED, 0);
            //lastDirection = myCanvas.LEFT;
            if((playerSprite.collidesWith(labirynt, true))||(playerSprite.collidesWith(level, true)))
                playerSprite.move(SPEED, 0);
            else
            {
                this.adjustViewport(this.viewPortX - SPEED, this.viewPortY);
                if (lastDirection != myCanvas.LEFT)
                {
                    //playerSprite.move(16, 0);
                    this.lastDirection = myCanvas.LEFT;
                    this.playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
            
        }
        else if(hdirection > 0)
        {
            playerSprite.move(SPEED, 0);
            //lastDirection = myCanvas.RIGHT;
            if((playerSprite.collidesWith(labirynt, true))||(playerSprite.collidesWith(level, true)))
                playerSprite.move(-SPEED, 0);
            else
            {
                this.adjustViewport(this.viewPortX + SPEED, this.viewPortY);
                if (lastDirection != myCanvas.RIGHT)
                {
                    this.lastDirection = myCanvas.RIGHT;
                    this.playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    this.playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
            }
            playerSpriteAnimator.forward();
     
        }
        else
        {
            //playerSprite.setFrame(1);
            playerSpriteAnimator.setMoving(false);
        } 

       /* if (hdirection < 0)
        {
                //if the previous direction was other than left set the sequence
                //correct sequence & transform needed for walking to the left
                if (this.lastDirection != myCanvas.LEFT)
                {
                    this.lastDirection = myCanvas.LEFT;
                    playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    playerSprite.setTransform(Sprite.TRANS_MIRROR);
                   // continue;
                }
                //assign the sequence playback direction
                playerSpriteAnimator.forward();
                //move the sprite to the left
                playerSprite.move(-SPEED, 0);
                //if moving the sprite generates a collision return sprite back
                //to its original position
                if(playerSprite.collidesWith(labirynt, true))
                playerSprite.move(SPEED, 0);
                //attempt to adjust the viewport to keep the sprite on the screen
                this.adjustViewport(this.viewPortX - SPEED, this.viewPortY);
                }
            else if (hdirection > 0)
            {
                if (this.lastDirection != myCanvas.RIGHT) {
                    this.lastDirection = myCanvas.RIGHT;
                    playerSprite.setFrameSequence(dyniaDesign.goLeft);
                    playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
                playerSpriteAnimator.forward();
                playerSprite.move(SPEED, 0);
                if(playerSprite.collidesWith(labirynt, true))
                    playerSprite.move(-SPEED, 0);

                this.adjustViewport(this.viewPortX + SPEED, this.viewPortY);
            }
            else if (vdirection < 0)
            {
                if (this.lastDirection != myCanvas.UP) {
                    this.lastDirection = myCanvas.UP;
                    playerSprite.setFrameSequence(dyniaDesign.goUp);
                    playerSprite.setTransform(Sprite.TRANS_NONE);
                   // continue;
                }
                playerSpriteAnimator.forward();
                playerSprite.move(0, -SPEED);
                if(playerSprite.collidesWith(labirynt, true))
                    playerSprite.move(0, SPEED);

                this.adjustViewport(this.viewPortX, this.viewPortY - SPEED);
            }
            else if (vdirection < 0)
            {
                if (this.lastDirection != myCanvas.DOWN) {
                    this.lastDirection = myCanvas.DOWN;
                    playerSprite.setFrameSequence(dyniaDesign.goDown);
                    playerSprite.setTransform(Sprite.TRANS_NONE);
                    //continue;
                }
                playerSpriteAnimator.forward();
                playerSprite.move(0, SPEED);
                if(playerSprite.collidesWith(labirynt, true))
                    playerSprite.move(0, -SPEED);

                this.adjustViewport(this.viewPortX, this.viewPortY + SPEED);
            }
            else
            {
                 playerSpriteAnimator.setMoving(false);
            }

*/
    }

    private class SpriteAnimationTask extends TimerTask
    {

        private boolean moving = false;
        private boolean forward = true;
        private Sprite sprite;

        public SpriteAnimationTask(Sprite sprite, boolean forward)
        {
            this.sprite = sprite;
            this.forward = forward;
        }

        public void run()
        {
            if (!this.moving)
            {
                return;
            }
            if (this.forward)
            {
                this.sprite.nextFrame();
            }
            else
            {
                this.sprite.prevFrame();
            }
        }

        public void forward()
        {
            this.forward = true;
            this.moving = true;
        }

        public void backward()
        {
            this.forward = false;
            this.moving = true;
        }

        public void setMoving(boolean isMoving)
        {
            this.moving = isMoving;
        }
    }

}
